package domein;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import javax.swing.JScrollBar;
import view.ClientForm;

/**
 * @author Colin Bundervoet
 * @author Jeroen Pattyn
 * @author Bram Schotte
 * @author Lucas Van Overberghe
 */
public class Client {

    private String server;
    private int port;
    private String username;
    private BufferedReader reader;
    private PrintWriter writer;
    private boolean connected;
    private ClientForm form;
    private Socket socket;

    public Client(String server, int port, String username) {
        this.server = server;
        this.port = port;
        this.username = username;
    }

    public void setForm(ClientForm form) {
        this.form = form;
    }

    public void connectClient() {
        form.getUsernameField().setEditable(false);
        if (connected == false) {
            try {
                socket = new Socket(server, port);
                reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                writer = new PrintWriter(socket.getOutputStream());

                connected = true;
                display("/nick " + username);

            } catch (UnknownHostException ex) {
                System.err.println(ex.getStackTrace());
                showInChat("Cannot connect to " + server + ". Please try again\n");
                form.getUsernameField().setEditable(true);
            } catch (IOException ex) {
                System.err.println(ex.getStackTrace());
                showInChat("Cannot connect. Please try again\n");
                form.getUsernameField().setEditable(true);
            }
            ServerListener l = new ServerListener();
            l.run();
        } else {
            showInChat("You are already connected!\n");
        }

    }

    public void display(String message) {
        SimpleDateFormat date = new SimpleDateFormat();
        try {
            String[] lines = message.split("\n");
            if (lines[0].startsWith("/")) {
                writer.println(lines[0]);
                writer.flush();
            } else {
                for (String line : lines) {
                    if (line.equals("")) {
                        writer.println(" ");
                    } else {
                        writer.println(line);
                    }
                    writer.flush();
                }
            }

        } catch (Exception ex) {
            showInChat("Message was not send");
        }

    }

    public void showInChat(String message) {
        SimpleDateFormat date = new SimpleDateFormat();
        String time = date.format(new Date());
        form.getChatTextArea().append(time + ": " + message + "\n");
        JScrollBar s = form.getjScrollPane2().getVerticalScrollBar();
        s.setValue(s.getMaximum());
    }

    public void disconnect() {
        try {
            if (this.connected) {
                showInChat("You have disconnected");
                display("/dc");
                writer.close();
                reader.close();
                socket.close();
            }
            form.getUsernameField().setEditable(true);
        } catch (IOException ex) {
            System.err.println(ex.getStackTrace());
        }
    }

    private class ServerListener implements Runnable {

        String message;
        @Override
        public void run() {
            try {
                while ((message = reader.readLine()) != null) {
                    if (message.startsWith("¥")) {
                        String[] data = message.split("¤");
                        String[] newData = Arrays.copyOfRange(data, 1, data.length);
                        form.getOnlineUsersList().setListData(newData);
                        form.getOnlineUsersList().repaint();
                    } else {
                        showInChat(message);
                    }
                }
            }
            catch (IOException ex) {
                System.err.println(ex.getStackTrace());
                disconnect();
            }
        }
    }

    public boolean isConnected() {
        return connected;
    }

    public void setConnected(boolean connected) {
        this.connected = connected;
    }
}
